package NetworkTool

import (
	"encoding/binary"
	"fmt"
	"net"
)

// 监听
func CreateTCPListener(addr string) (*net.TCPListener, error) {
	tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
	if err != nil {
		return nil, err
	}
	tcpListener, err := net.ListenTCP("tcp", tcpAddr)
	if err != nil {
		return nil, err
	}
	return tcpListener, nil
}

// 连接
func CreateTCPConn(addr string) (*net.TCPConn, error) {
	tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
	if err != nil {
		return nil, err
	}
	tcpListener, err := net.DialTCP("tcp", nil, tcpAddr)
	if err != nil {
		return nil, err
	}
	return tcpListener, nil
}

// 发送消息(根据请求头获取长度防止粘包)
func sendMessage(conn net.Conn, data []byte) error {
	// 获取消息长度
	length := uint64(len(data))

	// 发送消息长度（8字节的uint64）
	err := binary.Write(conn, binary.BigEndian, length)
	if err != nil {
		return fmt.Errorf("发送消息长度错误: %v", err)
	}

	// 发送消息体
	_, err = conn.Write(data)
	if err != nil {
		return fmt.Errorf("发送消息体错误: %v", err)
	}

	return nil
}

// 接收信息(根据请求头获取长度防止粘包)
func receiveMessage(conn net.Conn) ([]byte, error) {
	// 读取消息长度（8字节的uint64）
	var length uint64
	err := binary.Read(conn, binary.BigEndian, &length)
	if err != nil {
		return nil, fmt.Errorf("读取消息长度错误: %v", err)
	}

	// 读取消息体
	data := make([]byte, length)
	_, err = conn.Read(data)
	if err != nil {
		return nil, fmt.Errorf("读取消息体错误: %v", err)
	}

	return data, nil
}

/* 用法例子 */
/*


func main() {
	// 连接到接收方
	address := "localhost:13001"
	conn, err := network.CreateTCPConn(address)
	if err != nil {
		fmt.Println("连接错误:", err)
		return
	}
	defer conn.Close()

	// 生成一个0到99之间的随机整数
	rand.Seed(time.Now().UnixNano())
	randomInt := rand.Intn(1000)

	// 发送消息
	messages := []string{
		"Hello, World!",
		"这是一个测试消息。",
		"粘包问题解决了！",
	}

	for _, msg := range messages {
		msg = msg + strconv.Itoa(randomInt)
		err := sendMessage(conn, msg)
		if err != nil {
			fmt.Println("发送消息错误:", err)
			return
		}
		fmt.Println("已发送消息:", msg)

		response, err := receiveMessage(conn)
		if err != nil {
			fmt.Println("接收返回信息错误:", err)
			return
		}
		fmt.Println("接收到返回信息:", response)
		time.Sleep(time.Second * 3)
	}
	time.Sleep(time.Second * 2)
}

*/
